import { getMusicIndexByNote } from '@/lib/music/data'
import { MusicPlayerSong } from '@/types/music'
import * as Tone from '@tonejs/midi'
import { combinationNotesHandler } from './musicNote'

// @ts-ignore
const ToneMidi: typeof Tone.Midi = Tone.Midi

/**
 * 导出midi
 * @param song
 */
export const exportMidi = (song: MusicPlayerSong) => {
  const midi = new ToneMidi()
  midi.name = song.name
  const track = midi.addTrack()
  track.name = song.name
  song.data.forEach((note) => {
    track.addNote({
      ticks: note.time,
      name: note.note,
      duration: 0.5,
    })
  })
  //   midi.duration = song.playerTime / 1000
  const buffer = midi.toArray()
  const file = new File([buffer], `${song.name}.mid`, { type: 'audio/midi' })
  return file
  //   下载
  //   const url = URL.createObjectURL(file)
  //   const a = document.createElement('a')
  //   a.href = url
  //   a.download = `${song.name}.mid`
  //   a.click()
}

export type NonExistentNote = {
  note: string
  count: number
  replaceNote: string | null
}
/**
 * 导入midi
 * @param name
 * @param chanks
 * @param midi
 * @param nonExistentNotes
 * @returns
 */
export function loadSongFromMidi(
  name: string,
  chanks: Tone.Midi['tracks'],
  midi: Tone.Midi,
  nonExistentNotes: NonExistentNote[],
  keyboardExclude: boolean,
  timeScale: number
) {
  let notes: MusicPlayerSong['data'] = []
  // console.log(midi)
  const ticksToDurationScale = (midi.duration * 1000) / midi.durationTicks
  const playerTime = Math.round(midi.duration * 1000 * timeScale)
  nonExistentNotes = nonExistentNotes.filter(
    (item) => item.replaceNote !== null
  )
  chanks.forEach((track) => {
    track.notes.forEach((note) => {
      const index = nonExistentNotes.findIndex(
        (item) => item.note === note.name
      )
      if (index !== -1) {
        note.name = nonExistentNotes[index].replaceNote!
      }
      notes.push({
        note: note.name,
        time: Math.round(note.ticks * ticksToDurationScale),
      })
    })
  })
  notes.sort((a, b) => a.time - b.time)
  if (keyboardExclude) {
    notes = keyboardExcludeHandler(notes)
  }
  notes.forEach((item) => (item.time = Math.round(item.time * timeScale)))
  const song: MusicPlayerSong = {
    name,
    playerTime,
    data: notes,
  }
  return song
}

function keyboardExcludeHandler(notes: MusicPlayerSong['data']) {
  const list = combinationNotesHandler(notes)
  for (let i = 0; i < list.length; i++) {
    let isBlack = list[i].find(
      (item) => getMusicIndexByNote(item.note).type == 'black'
    )
    let isWhite = list[i].find(
      (item) => getMusicIndexByNote(item.note).type == 'white'
    )
    if (isBlack && isWhite) {
      list[i] = list[i].filter(
        (item) => getMusicIndexByNote(item.note).type == 'white'
      )
    }
  }
  // console.log(list.flat())

  return list.flat()
  // return notes.filter((item) => !keyboardExclude.includes(item.note))
}

export default ToneMidi
